home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / gnushogi.lha / gnushogi-1.1 / src / gnuan.c < prev    next >
C/C++ Source or Header  |  1993-04-16  |  23KB  |  1,026 lines

  1. /*
  2.  * gnuan.c - Analysis interface for gnushogi.
  3.  *
  4.  * Copyright (c) 1993 Matthias Mutz
  5.  *
  6.  * gnuan was originally the analysis interface for gnuchess
  7.  *
  8.  * Copyright (c) 1988,1989,1990 John Stanback
  9.  * Copyright (c) 1992 Free Software Foundation
  10.  *
  11.  * This file is part of GNU SHOGI.
  12.  *
  13.  * GNU Shogi is free software; you can redistribute it and/or modify
  14.  * it under the terms of the GNU General Public License as published by
  15.  * the Free Software Foundation; either version 1, or (at your option)
  16.  * any later version.
  17.  *
  18.  * GNU Shogi is distributed in the hope that it will be useful,
  19.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21.  * GNU General Public License for more details.
  22.  *
  23.  * You should have received a copy of the GNU General Public License
  24.  * along with GNU Shogi; see the file COPYING.  If not, write to
  25.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  26.  */
  27.  
  28. /*
  29.  * This is a front end for a shogi analysis program.  It takes a file of
  30.  * moves in algebraic notation and creates a file containing each move that
  31.  * was made, the move it would have made, the score it would give itself
  32.  * after making the move it recommended, and the depth it searched for the
  33.  * move.
  34.  *
  35.  * This is a modification of nondsp.c.  I have cut out code that was not needed
  36.  * for this application such as the help and edit functions.  Most of the
  37.  * modifications were done in InputCommand.
  38.  */
  39.  
  40. /*
  41.  * This file will generate two different analysis programs.  One is meant to
  42.  * be run as a background process inwhich the in and out files are
  43.  * predefined. The other is meant to be run in the foreground where it will
  44.  * prompt you for the name of the file with the game in it, the maximum depth
  45.  * the search should be conducted to and the time limit per move.  It would
  46.  * be nice to be able to give these parameters on the command line, but that
  47.  * would mean changing main which is in the gnuchess.c file.
  48.  *
  49.  * For each move it will analyse the move until either it has run out of time or
  50.  * it has reached the maximum depth.
  51.  *
  52.  * To build the version for background processing define BACKGROUND_ANALYSIS
  53.  * either at the top of this file, or in compilation.  The files and depth
  54.  * used are defined below.  They are MAX_DEPTH, MAX_TIME, OUT_FILE, IN_FILE
  55.  * and PROG_FILE.  The PROG_FILE is a file that will be updated as each move
  56.  * is analysed so you can check its progress.  This is only updated when
  57.  * running the BACKGROUND_ANALYSIS version.  In the version where the
  58.  * filename and depth are entered at runtime, the output goes to stdout.
  59.  */
  60.  
  61. #define BACKGROUND_ANALYSIS 0
  62.  
  63. #define MAX_DEPTH  MAXDEPTH
  64. #define MAX_TIME   20
  65. #define OUT_FILE   "gnuan.out"
  66. #define IN_FILE    "gnuan.in"
  67. #define PROG_FILE  "gnuan.prog"
  68.  
  69.  
  70. #include <ctype.h>
  71. #include <signal.h>
  72. #ifdef MSDOS
  73. #include <dos.h>
  74. #include <conio.h>
  75. #include <stdlib.h>
  76. #include <string.h>
  77. #include <time.h>
  78. #else
  79. #include <sys/param.h>
  80. #include <sys/types.h>
  81. #include <sys/file.h>
  82. #include <sys/ioctl.h>
  83. void TerminateSearch (int), Die (int);
  84.  
  85. #endif /* MSDOS */
  86.  
  87. #include "gnushogi.h"
  88. #include "ataks.h"
  89. #undef rxx
  90. #undef cxx
  91. #undef scanz
  92. #undef printz
  93.  
  94. #define rxx "ihgfedcba"
  95. #define cxx "987654321"
  96.  
  97. #define scanz scanf
  98. #define printz printf
  99.  
  100. char mvstr[4][6];
  101. extern char *ColorStr[2];
  102. int mycnt1, mycnt2;
  103.  
  104. static FILE *fpin;
  105. static FILE *fpout;
  106. int samedepth = false;
  107. char *DRAW;
  108. unsigned short int MV[MAXDEPTH];
  109. enum
  110. {
  111.   XSHOGI, GNUSHOGI, OTHER
  112. } InFileType;
  113. char InBuf[256];
  114.  
  115. #ifdef BACKGROUND_ANALYSIS
  116. static FILE *fpprog;
  117.  
  118. #endif
  119. static char black_actual_move[20];
  120. static char white_actual_move[20];
  121. static char black_suggest_move[20];
  122. static char white_suggest_move[20];
  123. static int sdw,sdb;
  124. static int black_score;
  125. static int white_score;
  126. int tmpscore;
  127. static int black_moving;
  128. static int current_depth;
  129. static int current_score;
  130. static int enable_update_display = 0;
  131.  
  132.  
  133. void
  134. Initialize (void)
  135. {
  136.   mycnt1 = mycnt2 = 0;
  137. }
  138.  
  139. void
  140. ExitChess (void)
  141. {
  142.   ListGame ();
  143.   exit (0);
  144. }
  145.  
  146. #ifndef MSDOS            /* never called!!! */
  147. void
  148. Die (int sig)
  149. {
  150.   ExitChess ();
  151. }
  152.  
  153. #endif /* MSDOS */
  154.  
  155. void
  156. TerminateSearch (int sig)
  157. {
  158. #ifdef MSDOS
  159.   sig++;            /* shut up the compiler */
  160. #endif /* MSDOS */
  161.   if (!flag.timeout)
  162.     flag.musttimeout = true;
  163.   flag.bothsides = false;
  164. }
  165.  
  166. void
  167. algbr (short int f, short int t, short int flag)
  168.  
  169. /*
  170.  * Generate move strings in different formats.
  171.  */
  172. {
  173.   int m3p;
  174.  
  175.   if ( f > NO_SQUARES ) 
  176.     { short piece;
  177.       piece = f - NO_SQUARES;
  178.       if ( f > (NO_SQUARES+NO_PIECES) )
  179.         piece -= NO_PIECES;
  180.       flag = (dropmask | piece); 
  181.     }
  182.   if ( (t & 0x80) != 0 )
  183.     {
  184.       flag |= promote;
  185.       t &= 0x7f;
  186.     }
  187.   if ( f == t && (f != 0 || t != 0) ) 
  188.     { 
  189.       mvstr[0][0] = mvstr[1][0] = mvstr[2][0] = mvstr[3][0] = '\0';
  190.     }
  191.   else
  192.   if ( (flag & dropmask) != 0 )
  193.     { short piece = flag & pmask;
  194.       mvstr[0][0] = pxx[piece];
  195.       mvstr[0][1] = '*';
  196.       mvstr[0][2] = cxx[column (t)];
  197.       mvstr[0][3] = rxx[row (t)];
  198.       mvstr[0][4] = '\0';
  199.       strcpy (mvstr[1], mvstr[0]);
  200.       strcpy (mvstr[2], mvstr[0]);
  201.       strcpy (mvstr[3], mvstr[0]);
  202.     }
  203.   else
  204.   if (f != 0 || t != 0)
  205.     {
  206.       /* algebraic notation */
  207.       mvstr[0][0] = cxx[column (f)];
  208.       mvstr[0][1] = rxx[row (f)];
  209.       mvstr[0][2] = cxx[column (t)];
  210.       mvstr[0][3] = rxx[row (t)];
  211.       mvstr[0][4] = mvstr[3][0] = '\0';
  212.       mvstr[1][0] = pxx[board[f]];
  213.  
  214.       mvstr[2][0] = mvstr[1][0];
  215.       mvstr[2][1] = mvstr[0][1]; 
  216.  
  217.       mvstr[2][2] = mvstr[1][1] = mvstr[0][2];    /* to column */
  218.       mvstr[2][3] = mvstr[1][2] = mvstr[0][3];    /* to row */
  219.       mvstr[2][4] = mvstr[1][3] = '\0';
  220.       strcpy (mvstr[3], mvstr[2]);
  221.       mvstr[3][1] = mvstr[0][0];
  222.       if (flag & promote)
  223.         {
  224.           strcat(mvstr[0], "+");
  225.           strcat(mvstr[1], "+");
  226.           strcat(mvstr[2], "+");
  227.           strcat(mvstr[3], "+");
  228.         }
  229.     }
  230.   else
  231.     mvstr[0][0] = mvstr[1][0] = mvstr[2][0] = mvstr[3][0] = '\0';
  232. }
  233.  
  234.  
  235.  
  236.  
  237. int
  238. VerifyMove (char *s, short int iop, unsigned short int *mv)
  239.  
  240. /*
  241.  * Compare the string 's' to the list of legal moves available for the
  242.  * opponent. If a match is found, make the move on the board.
  243.  */
  244.  
  245. {
  246.   static short pnt, tempb, tempc, tempsf, tempst, cnt;
  247.   static struct leaf xnode;
  248.   struct leaf *node;
  249.  
  250.   *mv = 0;
  251.   if (iop == 2)
  252.     {
  253.       UnmakeMove (opponent, &xnode, &tempb, &tempc, &tempsf, &tempst);
  254.       return (false);
  255.     }
  256.   cnt = 0;
  257.   MoveList (opponent, 2);
  258.   pnt = TrPnt[2];
  259.   while (pnt < TrPnt[3])
  260.     {
  261.       node = &Tree[pnt++];
  262.       algbr (node->f, node->t, (short) node->flags);
  263.       if (strcmp (s, mvstr[0]) == 0 || strcmp (s, mvstr[1]) == 0 ||
  264.       strcmp (s, mvstr[2]) == 0 || strcmp (s, mvstr[3]) == 0)
  265.     {
  266.       cnt++;
  267.       xnode = *node;
  268.     }
  269.     }
  270.   if (cnt == 1)
  271.     {
  272.       MakeMove (opponent, &xnode, &tempb, &tempc, &tempsf, &tempst, &BADscore);
  273.       if (SqAtakd (PieceList[opponent][0], computer))
  274.     {
  275.       UnmakeMove (opponent, &xnode, &tempb, &tempc, &tempsf, &tempst);
  276.       printz ("Illegal move\n");
  277.       return (false);
  278.     }
  279.       else
  280.     {
  281.       if (iop == 1)
  282.         return (true);
  283.  
  284.       /*
  285.            * UpdateDisplay (xnode.f, xnode.t, 0, (short) xnode.flags);
  286.            */
  287.       GameList[GameCnt].depth = GameList[GameCnt].score = 0;
  288.       GameList[GameCnt].nodes = 0;
  289.       ElapsedTime (1);
  290.       GameList[GameCnt].time = (short) et;
  291.       TimeControl.clock[opponent] -= et;
  292.       --TimeControl.moves[opponent];
  293.       *mv = (xnode.f << 8) | xnode.t;
  294.       algbr (xnode.f, xnode.t, false);
  295.       return (true);
  296.     }
  297.     }
  298. #ifdef CHESSTOOL
  299.   printz ("Illegal move\n");
  300. #else
  301.   if (cnt > 1)
  302.     ShowMessage ("Ambiguous Move!");
  303. #endif
  304. if(cnt == 0){
  305.  pnt = TrPnt[2];
  306.   while (pnt < TrPnt[3])
  307.     {
  308.       node = &Tree[pnt++];
  309.       algbr (node->f, node->t, (short) node->flags);
  310.       printf("%s -> %s\n",s,mvstr[0]);
  311.     }
  312.   }
  313.   return (false);
  314. }
  315.  
  316. void
  317. help (void)
  318. {
  319. }
  320.  
  321. void
  322. EditBoard (void)
  323.  
  324. /*
  325.  * Set up a board position. Pieces are entered by typing the piece followed
  326.  * by the location. For example, Nf3 will place a knight on square f3.
  327.  */
  328.  
  329. {
  330. }
  331.  
  332. void
  333. SetupBoard (void)
  334.  
  335. /*
  336.  * Compatibility with Unix chess and the nchesstool. Set up a board position.
  337.  * Eight lines of eight characters are used to setup the board. a8-h8 is the
  338.  * first line. White pieces are  represented  by  uppercase characters.
  339.  */
  340.  
  341. {
  342. }
  343.  
  344. void
  345. ShowDepth (char ch)
  346. {
  347. #ifdef MSDOS
  348.   ch++;                /* shut up the compiler */
  349. #endif /* MSDOS */
  350. }
  351.  
  352. void
  353. ShowResults (short int score, unsigned short int *bstline, char ch)
  354. {
  355.   int i;
  356.  
  357.   current_score = score;
  358.   current_depth = Sdepth;
  359.   for (i = 1; bstline[i] > 0; i++)
  360.     {
  361.       MV[i] = bstline[i];
  362.     } MV[i] = 0;
  363. }
  364.  
  365. void
  366. SearchStartStuff (short int side)
  367. {
  368.   signal (SIGINT, TerminateSearch);
  369. #ifndef MSDOS
  370.   signal (SIGQUIT, TerminateSearch);
  371. #endif /* MSDOS */
  372.   if (flag.post)
  373.     {
  374.       fprintf (stderr, "\nMove# %d    Target= %ld    Clock: %ld\n",
  375.            TCmoves - TimeControl.moves[side] + 1,
  376.            ResponseTime, TimeControl.clock[side]);
  377.     }
  378. }
  379.  
  380. void
  381. OutputMove (void)
  382. {
  383.   if (black_moving)
  384.     {
  385.       strcpy (black_suggest_move, mvstr[0]);
  386.       black_score = current_score;
  387.     }
  388.   else
  389.     {
  390.       strcpy (white_suggest_move, mvstr[0]);
  391.       white_score = current_score;
  392.     }
  393. }
  394.  
  395. void
  396. ElapsedTime (short int iop)
  397.  
  398. /*
  399.  * Determine the time that has passed since the search was started. If the
  400.  * elapsed time exceeds the target (ResponseTime+ExtraTime) then set timeout
  401.  * to true which will terminate the search.
  402.  */
  403. {
  404.   if (ahead)
  405.     {
  406. #ifndef MSDOS
  407. #ifdef FIONREAD
  408.       long nchar;
  409.  
  410.       ioctl (0, FIONREAD, &nchar);
  411.       if (nchar)
  412.     {
  413.       flag.timeout = true;
  414.       flag.bothsides = false;
  415.     }
  416. #endif
  417. #else
  418.       if (kbhit ())
  419.     {
  420.       flag.timeout = true;
  421.       flag.bothsides = false;
  422.     }
  423. #endif /* MSDOS */
  424.     }
  425.   et = (time ((long *) 0) - time0) * 100;
  426.   if (et < 0)
  427.     et = 0;
  428.   ETnodes += ZNODES;
  429.   if (iop == 1)
  430.     {
  431.       if (et > ResponseTime + ExtraTime && Sdepth > 1)
  432.     flag.timeout = true;
  433.       time0 = time ((long *) 0);
  434.       ETnodes = NodeCnt + ZNODES;
  435.     }
  436. }
  437.  
  438. void
  439. SetTimeControl (void)
  440. {
  441.   if (TCflag)
  442.     {
  443.       TimeControl.moves[black] = TimeControl.moves[white] = TCmoves;
  444.       TimeControl.clock[black] = TimeControl.clock[white] = 6000L * TCminutes;
  445.     }
  446.   else
  447.     {
  448.       TimeControl.moves[black] = TimeControl.moves[white] = 0;
  449.       TimeControl.clock[black] = TimeControl.clock[white] = 0;
  450.       MaxResponseTime = 6000L * TCminutes;
  451.     }
  452.   et = 0;
  453.   ElapsedTime (1);
  454. }
  455.  
  456. void
  457. ClrScreen (void)
  458. {
  459. #ifndef CHESSTOOL
  460.   printz ("\n");
  461. #endif
  462. }
  463.  
  464. void
  465. UpdateDisplay (short int f, short int t, short int redraw, short int isspec)
  466. {
  467. #ifndef CHESSTOOL
  468.   short r, c, l;
  469.  
  470.   if (!enable_update_display)
  471.     return;
  472.   if (redraw)
  473.     {
  474.       fprintf (fpout, "\n");
  475.       for (r = (NO_ROWS-1); r >= 0; r--)
  476.     {
  477.       for (c = 0; c <= (NO_COLS-1); c++)
  478.         { char pc;
  479.           l = locn (r, c);
  480.           pc = (is_promoted[board[l]] ? '+' : ' ');
  481.           if (color[l] == neutral)
  482.         fprintf (fpout, " -");
  483.           else if (color[l] == black)
  484.         fprintf (fpout, "%c%c", pc, qxx[board[l]]);
  485.           else
  486.         fprintf (fpout, "%c%c", pc, pxx[board[l]]);
  487.         }
  488.       fprintf (fpout, "\n");
  489.     }
  490.       fprintf (fpout, "\n");
  491.       {  
  492.     short side;
  493.     for (side = black; side <= white; side++)
  494.       { short piece, c; 
  495.         fprintf(fpout, (side==black)?"black ":"white ");
  496.             for (piece = pawn; piece <= king; piece++)
  497.           if (c = Captured[side][piece]) 
  498.         fprintf(fpout, "%i%c ",c,pxx[piece]);
  499.             fprintf(fpout, "\n");
  500.           };
  501.       }
  502.     }
  503. #endif /* CHESSTOOL */
  504. #ifdef MSDOS
  505.   f++;
  506.   t++;
  507.   isspec++;            /* shut up the compiler */
  508. #endif /* MSDOS */
  509. }
  510.  
  511. void
  512. GetGame (void)
  513. {
  514. }
  515.  
  516. void
  517. SaveGame (void)
  518. {
  519. }
  520.  
  521. void
  522. ListGame (void)
  523. {
  524. }
  525.  
  526. void
  527. Undo (void)
  528.  
  529. /*
  530.  * Undo the most recent half-move.
  531.  */
  532.  
  533. {
  534.   short f, t;
  535.   f = GameList[GameCnt].gmove >> 8;
  536.   t = GameList[GameCnt].gmove & 0x7F;
  537.    if ( f > NO_SQUARES )
  538.      { /* the move was a drop */
  539.         Captured[color[t]][board[t]]++;
  540.     board[t] = no_piece;
  541.     color[t] = neutral;
  542.     Mvboard[t]--;
  543.      }
  544.    else
  545.      {
  546.     if ( GameList[GameCnt].flags & promote )
  547.       board[f] = unpromoted[board[t]];
  548.     else
  549.       board[f] = board[t];
  550.     color[f] = color[t];
  551.     board[t] = GameList[GameCnt].piece;
  552.     color[t] = GameList[GameCnt].color;
  553.     if ( board[t] != no_piece )
  554.       Captured[color[f]][unpromoted[board[t]]]--;
  555.     if (color[t] != neutral)
  556.       Mvboard[t]--;
  557.         Mvboard[f]--;
  558.      }
  559.    InitializeStats ();
  560.  
  561.   if (TCflag && (TCmoves>1))
  562.     ++TimeControl.moves[color[f]];
  563.   hashkey = GameList[GameCnt].hashkey;
  564.   hashbd = GameList[GameCnt].hashbd;
  565.   GameCnt--;
  566.   computer = computer ^ 1;
  567.   opponent = opponent ^ 1;
  568.   flag.mate = false;
  569.   Sdepth = 0;
  570.   player = player ^ 1;
  571.   ShowSidetoMove ();
  572.   UpdateDisplay (0, 0, 1, 0);
  573.   if (flag.regularstart)
  574.     Book = BOOKFAIL;
  575. }
  576.  
  577. void
  578. ShowMessage (char *s)
  579. {
  580.   fprintf (stderr, "%s\n", s);
  581. }
  582.  
  583. void
  584. ShowSidetoMove (void)
  585. {
  586. }
  587.  
  588. void
  589. PromptForMove (void)
  590. {
  591. #ifndef CHESSTOOL
  592.   printz ("\nYour move is? ");
  593. #endif /* CHESSTOOL */
  594. }
  595.  
  596.  
  597. void
  598. ShowCurrentMove (short int pnt, short int f, short int t)
  599. {
  600. #ifdef MSDOS
  601.   f++;
  602.   t++;
  603.   pnt++;            /* shut up the compiler */
  604. #endif /* MSDOS */
  605. }
  606.  
  607. void
  608. ChangeAlphaWindow (void)
  609. {
  610.   printz ("window: ");
  611. }
  612.  
  613. void
  614. ChangeBetaWindow (void)
  615. {
  616.   printz ("window: ");
  617. }
  618.  
  619. void
  620. GiveHint (void)
  621. {
  622.   algbr ((short) (hint >> 8), (short) (hint & 0xFF), false);
  623.   fprintf (stderr, "Hint: %s\n", mvstr[0]);
  624. }
  625.  
  626. void
  627. SelectLevel (char *sx)
  628. {
  629. }
  630.  
  631. void
  632. ChangeSearchDepth (void)
  633. {
  634.   printz ("depth= ");
  635.   scanz ("%hd", &MaxSearchDepth);
  636. }
  637.  
  638. void
  639. SetContempt (void)
  640. {
  641.   printz ("contempt= ");
  642.   scanz ("%hd", &contempt);
  643. }
  644.  
  645. void
  646. ChangeXwindow (void)
  647. {
  648.   printz ("xwndw= ");
  649.   scanz ("%hd", &xwndw);
  650. }
  651.  
  652. void
  653. TestSpeed (void (*f) (short int side, short int ply))
  654. {
  655.   short i;
  656.   long cnt, rate, t1, t2;
  657.  
  658.   t1 = time (0);
  659.   for (i = 0; i < 10000; i++)
  660.     {
  661.       f (opponent, 2);
  662.     }
  663.   t2 = time (0);
  664.   cnt = 10000L * (TrPnt[3] - TrPnt[2]);
  665.   rate = cnt / (t2 - t1);
  666.   printz ("Nodes= %ld Nodes/sec= %ld\n", cnt, rate);
  667. }
  668.  
  669.  
  670. #define copym() while(*p!=' ' && *p!='\n')  *q++ = *p++;  *q='\0';
  671. #define skipb() while(*p==' ')p++;
  672. #define skip() skipb(); while(*p!=' ' && *p!='\n')p++; skipb(); 
  673.  
  674. int
  675. GetNextMove (char *buffer)
  676. {
  677.   char cbuf[128];
  678.   char sdepth[128];
  679.   int sdindex;
  680.   char *p,*q;
  681.   sdw = sdb =0;
  682.   white_actual_move[0] = '\0';
  683.   black_actual_move[0] = '\0';
  684.   if(fgets(cbuf,sizeof(cbuf),fpin) != NULL){
  685.   p = cbuf;
  686.   for( ; *p; p++ ) {
  687.     if ( isalpha(*p) || isdigit(*p) ) {
  688.       q = black_actual_move;
  689.       copym();
  690.       if( strcmp(black_actual_move,"Book")==0) continue; else break;
  691.     }
  692.   }
  693.   if (*p == '\0' && black_actual_move[0] == '\0')return 0;
  694.   if(InFileType == GNUSHOGI){
  695.     skip(); /* score */
  696.     if ( samedepth ) {
  697.       sdindex = 0;
  698.       while (*p != ' ' && *p != '\n') sdepth[sdindex++] = *p++;
  699.       sdepth[sdindex] = '\0';
  700.       if(strcmp(sdepth,"Book")==0) {
  701.     sdw = -99;
  702.       } else
  703.     sdw = atoi(sdepth);
  704.     } else {
  705.     skip(); /* depth */
  706.     }
  707.     skip(); /* nodes */
  708.     skip(); /* time */
  709.   }
  710.  
  711.   for( ; *p; p++){
  712.     if(isalpha(*p) || isdigit(*p)){
  713.     q = white_actual_move;
  714.     copym();
  715.         if(strcmp(white_actual_move,"Book")==0) continue; else break;
  716.         break;
  717.     }
  718.   }
  719.   if (*p == '\0' && white_actual_move[0] == '\0')return 1;
  720.   if(InFileType == GNUSHOGI){
  721.       skip(); /* score */
  722.       if ( samedepth ) {
  723.     sdindex = 0;
  724.         while (*p != ' ' && *p != '\n') sdepth[sdindex++] = *p++;
  725.         sdepth[sdindex] = '\0';
  726.         if ( strcmp(sdepth,"Book")==0 )
  727.       sdb = -99;
  728.         else 
  729.       sdb = atoi(sdepth);
  730.     }
  731.   }
  732.  
  733.   return 1;
  734.   } else /* EOF */
  735.   return -1;
  736.  
  737. }
  738.  
  739. void
  740. InputCommand (void)
  741.  
  742. /*
  743.  * Open the file of moves to analyse.  Go through the file move by move and
  744.  * do the following for each move.  See what gnuchess would have done in that
  745.  * position.  Record the move it would have made along with the score it
  746.  * would have given and the search depth.  Take back its move. Force the move
  747.  * that was actually made.  Keep track of statistics such as how many moves
  748.  * agreed.
  749.  */
  750.  
  751. {
  752.   int i;
  753.   short ok;
  754.   unsigned short mv;
  755.   char s[80];
  756. #if !defined BACKGROUND_ANALYSIS
  757.   int max_minutes;
  758.   char inbuf[256];
  759. #else
  760.   char outfilename[255];
  761.   char progfilename[255];
  762. #endif
  763.   char infilename[255];
  764.   int search_depth;
  765.   int move_number = 1;
  766.   long start_time, end_time, elapsed_time;
  767.   int total_white_moves, total_black_moves;
  768.   int same_white_moves, same_black_moves;
  769.   float black_percent, white_percent;
  770.  
  771.   /* Initialize necessary variables. */
  772.  
  773.   flag.quit = false;
  774.   flag.beep = false;
  775.   player = opponent;
  776.   enable_update_display = 1;
  777.   ft = 0;
  778.   Book = false;
  779.   total_white_moves = 0;
  780.   total_black_moves = 0;
  781.   same_white_moves = 0;
  782.   same_black_moves = 0;
  783.  
  784. #ifdef BACKGROUND_ANALYSIS
  785.  
  786.   /*
  787.    * Set the in files to standard ones for analysis if background
  788.    * processing selected.
  789.    */
  790.  
  791.   strcpy (infilename, IN_FILE);
  792.   strcpy (outfilename, OUT_FILE);
  793.   strcpy (progfilename, PROG_FILE);
  794.   fpout = fopen (outfilename, "w");
  795.   if (fpout == NULL)
  796.     {
  797.       fprintf (fpout, "This file does not exist : %s\n", outfilename);
  798.       flag.quit = 1;
  799.       return;
  800.     }
  801.   MaxSearchDepth = search_depth = MAX_DEPTH;
  802.   TCminutes = MAX_TIME;
  803.  
  804. #else
  805.  
  806.   /* Request information on where the file is and the depth an time. */
  807.  
  808.   fpout = stderr;
  809.   fprintf (fpout, "Input the file with the algebraic moves of the game.\n");
  810.   fflush(fpout);
  811.   gets (infilename);
  812.   fprintf (fpout, "\n");
  813.   do
  814.     {
  815.       fprintf (fpout, "Input the search depth you want to use.  (1 to 29)(- for depth from file)\n");
  816.       gets (inbuf);
  817.       search_depth = atoi (inbuf);
  818.       if(search_depth < 0) {samedepth = true; search_depth = -search_depth;}
  819.   } while (search_depth < 1 || search_depth > 29);
  820.   MaxSearchDepth = search_depth;
  821.  
  822.   fprintf (fpout, "\n");
  823.   do
  824.     {
  825.       fprintf (fpout, "Input the maximum number of minutes per move you want to use.\n");
  826.       gets (inbuf);
  827.       max_minutes = atoi (inbuf);
  828.   } while (max_minutes < 1);
  829.   printf ("\nYou will search to %d half moves\n", search_depth);
  830.   printf ("\nWith no search taking more than %d minutes\n",max_minutes);
  831.   TCminutes = max_minutes;
  832.  
  833.   fprintf (fpout, "\n\n");
  834.  
  835. #endif
  836.  
  837.   fpin = fopen (infilename, "r");
  838.   if (fpin == NULL)
  839.     {
  840.       fprintf (fpout, "This file does not exist : %s\n", infilename);
  841.       flag.quit = 1;
  842.       return;
  843.     }
  844.   /* lets find out about this file */
  845.   fgets (InBuf, 256, fpin);
  846.   InFileType = OTHER;
  847.   if (!strncmp (InBuf, "xshogi", 6))
  848.     {
  849.       InFileType = XSHOGI;
  850.       fgets (InBuf, 256, fpin);
  851.       fgets (InBuf, 256, fpin);
  852.     }
  853.   else if (!strncmp (InBuf, "gnushogi", 6))
  854.     {
  855.       InFileType = GNUSHOGI;
  856.       fgets (InBuf, 256, fpin);
  857.     }
  858.   else
  859.     rewind (fpin);
  860.   TCmoves = 1;
  861.   TCflag = (TCmoves > 1);
  862.   OperatorTime = 0;
  863.   SetTimeControl ();
  864.  
  865.  
  866.   fprintf (fpout, "Move Black White      Score Depth     Best Line\n");
  867.   fprintf (fpout, "------------------------------------------------------------------\n");
  868.  
  869. #ifdef BACKGROUND_ANALYSIS
  870.  
  871.   /*
  872.    * Update progress in the progress file if this is running in the
  873.    * background.
  874.    */
  875.  
  876.   fpprog = fopen (progfilename, "w");
  877.   fprintf (fpprog, "Done with move #%d.\n", move_number - 1);
  878.   fclose (fpprog);
  879.  
  880. #endif
  881.  
  882.   time (&start_time);
  883.   while (1)
  884.     {
  885.       opponent = white;
  886.       computer = black;
  887.       player = computer;
  888.       black_moving = 1;
  889.       if (!GetNextMove (s))
  890.     {
  891.       flag.quit = 1;
  892.       break;
  893.     }
  894.     if(sdw == -99) MaxSearchDepth = search_depth; else
  895.       MaxSearchDepth = (sdw)?sdw:search_depth;
  896.       if (!strcmp (black_actual_move, "White") || !strcmp (black_actual_move, "Black") || !strcmp (black_actual_move, "draw"))
  897.     break;
  898.       flag.force = 0;
  899.       SelectMove (computer, 1);
  900.       Undo ();
  901.       flag.force = 1;
  902.       opponent = black;
  903.       computer = white;
  904.       player = opponent;
  905.       ok = VerifyMove (black_actual_move, 0, &mv);
  906. #ifdef notdef
  907.       ExaminePosition ();
  908.       tmpscore = ScorePosition (black);
  909. #endif
  910.       if (!ok)
  911.     {
  912.       fprintf (fpout, "\nBad move.  %s  Board position is: \n", s);
  913.       UpdateDisplay (0, 0, 1, 0);
  914.       flag.quit = 1;
  915.       break;
  916.     }
  917.       else
  918.     {
  919.       char  x[80];
  920.       strcpy (x, black_actual_move);
  921.       if (strcmp (black_actual_move, black_suggest_move))
  922.         strcat (x, "#");
  923. #ifdef notdef
  924.       fprintf (fpout, "%3d   %-9s      %5d%5d%5d   ", move_number, x,tmpscore, black_score, current_depth);
  925. #endif
  926.     if(sdw == -99)
  927.       fprintf (fpout, "%3d   %-9s      %5d   Book ", move_number, x, black_score, current_depth);
  928.     else
  929.       fprintf (fpout, "%3d   %-9s      %5d%5d   ", move_number, x, black_score, current_depth);
  930.       for (i = 1; MV[i] > 0; i++)
  931.         {
  932.           algbr ((short) (MV[i] >> 8), (short) (MV[i] & 0xFF), false);
  933.           fprintf (fpout,"%5s ", mvstr[0]);
  934.         }
  935.       fprintf (fpout,"\n");
  936.       fflush (fpout);
  937.       move_number++;
  938.       total_black_moves++;
  939.       if (!strcmp (black_actual_move, black_suggest_move))
  940.         same_black_moves++;
  941.       Sdepth = 0;
  942.       ft = 0;
  943.     }
  944.       player = computer;
  945.       black_moving = 0;
  946.     if(sdb == -99) MaxSearchDepth = search_depth; else
  947.       MaxSearchDepth = (sdb)?sdb:search_depth;
  948.       if (!strcmp (white_actual_move, "White") || !strcmp (white_actual_move, "Black") || !strcmp (white_actual_move, "draw"))
  949.     break;
  950.       flag.force = 0;
  951.       SelectMove (computer, 1);
  952.       Undo ();
  953.       flag.force = 1;
  954.       opponent = white;
  955.       computer = black;
  956.       player = opponent;
  957.       ok = VerifyMove (white_actual_move, 0, &mv);
  958. #ifdef notdef
  959.   ExaminePosition ();
  960.   tmpscore = ScorePosition (white);
  961. #endif
  962.       if (!ok)
  963.     {
  964.       fprintf (fpout, "\nBad move.  %s  Board position is: \n", s);
  965.       UpdateDisplay (0, 0, 1, 0);
  966.       flag.quit = 1;
  967.       break;
  968.     }
  969.       else
  970.     {
  971.       char x[8];
  972.       strcpy (x, white_actual_move);
  973.       if (strcmp (white_actual_move, white_suggest_move))
  974.         strcat (x, "#");
  975. #ifdef notdef
  976.       fprintf (fpout, "            %-9s%5d%5d%5d   ", x,tmpscore, white_score, current_depth);
  977. #endif
  978.     if(sdb == -99)
  979.       fprintf (fpout, "            %-9s%5d  Book  ", x, white_score, current_depth);
  980.     else
  981.       fprintf (fpout, "            %-9s%5d%5d   ", x, white_score, current_depth);
  982.       for (i = 1; MV[i] > 0; i++)
  983.         {
  984.           algbr ((short) (MV[i] >> 8), (short) (MV[i] & 0xFF), false);
  985.           fprintf (fpout,"%5s ", mvstr[0]);
  986.         }
  987.       fprintf (fpout,"\n");
  988.       fflush (fpout);
  989.  
  990. #ifdef BACKGROUND_ANALYSIS
  991.  
  992.       /*
  993.            * Update progress in the progress file if this is running in the
  994.            * background.
  995.            */
  996.  
  997.       fpprog = fopen (progfilename, "w");
  998.       fprintf (fpprog, "Done with move #%d.\n", move_number - 1);
  999.       fclose (fpprog);
  1000. #else
  1001.  
  1002.       /*
  1003.            * fprintf(stderr, "Done with move #%d.\n", move_number-1);
  1004.            */
  1005.  
  1006. #endif
  1007.  
  1008.       total_white_moves++;
  1009.       if (!strcmp (white_actual_move, white_suggest_move))
  1010.         same_white_moves++;
  1011.       Sdepth = 0;
  1012.       ft = 0;
  1013.     }
  1014.     }
  1015.  
  1016.   black_percent = ((float) same_black_moves) * 100 / (float) total_black_moves;
  1017.   white_percent = ((float) same_white_moves) * 100 / (float) total_white_moves;
  1018.   fprintf (fpout, "\n           Black's percentage was %5.2f%%.     White's percentage was %5.2f%%.\n", black_percent, white_percent);
  1019.   time (&end_time);
  1020.   elapsed_time = end_time - start_time;
  1021.   fprintf (fpout, "\n           Elapsed time was %d seconds.\n", elapsed_time);
  1022.   fclose (fpin);
  1023.   fclose (fpout);
  1024.   exit (0);
  1025. }
  1026.